/*
 Copyright (c) 2017-2020 ApolloZhu <public-apollonian@outlook.com>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 */

import XCTest
@testable import QRCodeSwift

private func expect(_ generator: @autoclosure () throws -> QRCode, withFill fill: String, andPatch patch: String, toMatch expected: String) throws {
    let qrCode = try generator()
    let generated = qrCode.toString(filledWith: fill, patchedWith: patch)
    XCTAssertEqual(generated, expected)
}

private extension UnicodeScalar {
    static let values = Array([0...0xD7FF, 0xE000...0x10FFFF].joined())
    static func randomElement(ignoredParameter: Int = 0) -> String {
        return "\(UnicodeScalar(values.randomElement()!)!)"
    }
}

private func randomStringOfUTF8Length(_ length: Int) -> String {
    var str = ""
    while str.utf8.count < length {
        str += UnicodeScalar.randomElement()
        if str.utf8.count > length {
            str = String(str.dropLast())
        }
    }
    return str
}

class QRCodeSwiftTests: XCTestCase {
    func testSimple() throws {
        try expect(QRCode("https://gist.github.com/agentgt/1700331"),
               withFill: "##", andPatch: "  ",
               toMatch: """
                                                                              
  ##############  ######      ##    ######          ####      ##############  
  ##          ##        ##          ########  ####    ##  ##  ##          ##  
  ##  ######  ##  ####  ##    ####  ##  ####    ####    ####  ##  ######  ##  
  ##  ######  ##    ##  ######  ####  ####          ##    ##  ##  ######  ##  
  ##  ######  ##  ##    ########  ##  ##          ##          ##  ######  ##  
  ##          ##    ##  ##    ######      ##  ##  ##      ##  ##          ##  
  ##############  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##  ##############  
                  ##              ##  ##  ######      ######                  
            ####    ########        ##  ########  ##          ##  ##  ##  ##  
      ####        ##    ##  ##    ####  ######      ##      ##    ######      
  ##    ##  ########  ##    ##              ##      ####      ######  ######  
  ########  ##      ##    ##    ##  ##    ##  ##  ##  ######  ##        ##    
  ##        ####  ##    ######  ########    ########          ####            
  ####      ##  ############  ####  ##    ##            ######  ##    ####    
  ####  ####  ##    ##        ##    ##  ####  ####  ##  ##      ##  ##  ####  
                ##  ##    ####          ####  ##      ####  ####  ########    
  ##  ##  ######      ##  ##    ####  ##    ##  ######    ######  ##  ##  ##  
                ############  ##  ####    ##  ##  ##    ######  ##  ##        
  ####  ########  ##    ######  ####  ##      ######    ####  ##    ####  ##  
  ##########      ####    ######  ##  ##############  ##    ##  ##      ##    
          ######      ##  ####  ########    ##      ####    ################  
    ##  ##  ##    ##  ##  ####        ##  ########  ##  ####    ######  ##    
      ####    ##  ##  ########      ####  ####  ##  ######    ##          ##  
  ##########        ##  ##########      ##  ####  ####  ##  ##  ##      ####  
    ##    ##############  ####  ####      ##      ####    ######    ##  ####  
  ##  ##            ########  ##        ##    ##            ##                
  ##      ##########  ########  ####  ##        ############  ##    ##  ####  
  ##  ##  ##      ######    ####    ####    ######        ####    ##  ####    
  ##  ####    ####        ######  ##      ##    ##  ################  ##  ##  
                  ####  ####      ####  ######  ######    ##      ####  ##    
  ##############          ##  ####  ######      ##        ##  ##  ######  ##  
  ##          ##  ####    ####  ##      ##    ####      ####      ####  ####  
  ##  ######  ##      ####    ######  ##    ######  ################  ##      
  ##  ######  ##        ##    ########    ####    ##  ######  ##    ##        
  ##  ######  ##    ##      ##  ##  ####  ######      ##    ##  ##  ####  ##  
  ##          ##        ##    ##  ####  ######    ##      ############    ##  
  ##############      ####    ######  ##  ##    ####  ##  ######    ##    ##  
                                                                              
""")
    }

    func testLowErrorCorrectLevel() throws {
        try expect( QRCode("https://passport.bilibili.com/qrcode/h5/login?oauthKey=2f3ab118e214e7ad69683df50918a481",
                      errorCorrectLevel: .L),
               withFill: "@@", andPatch: "  ",
               toMatch: """
                                                                              
  @@@@@@@@@@@@@@  @@        @@  @@        @@@@  @@  @@@@@@@@  @@@@@@@@@@@@@@  
  @@          @@  @@    @@@@@@@@    @@  @@        @@  @@      @@          @@  
  @@  @@@@@@  @@  @@@@    @@  @@@@@@@@@@  @@@@@@@@@@  @@  @@  @@  @@@@@@  @@  
  @@  @@@@@@  @@  @@@@@@  @@          @@    @@  @@@@@@@@@@    @@  @@@@@@  @@  
  @@  @@@@@@  @@    @@@@  @@  @@@@    @@    @@  @@    @@@@@@  @@  @@@@@@  @@  
  @@          @@  @@@@@@              @@@@@@@@            @@  @@          @@  
  @@@@@@@@@@@@@@  @@  @@  @@  @@  @@  @@  @@  @@  @@  @@  @@  @@@@@@@@@@@@@@  
                      @@@@  @@  @@  @@@@  @@@@  @@@@  @@@@@@                  
  @@@@    @@@@@@      @@  @@@@    @@@@  @@  @@@@          @@    @@  @@@@@@@@  
        @@@@@@              @@@@@@    @@  @@    @@  @@@@@@@@      @@  @@@@    
  @@@@@@@@@@@@@@@@              @@  @@@@  @@@@  @@@@  @@@@  @@@@  @@@@  @@    
    @@@@    @@    @@      @@  @@@@@@@@      @@  @@                  @@@@  @@  
        @@    @@  @@@@@@@@  @@@@    @@@@@@  @@@@  @@    @@  @@@@@@    @@  @@  
  @@      @@        @@@@  @@    @@@@      @@@@@@@@  @@@@@@        @@@@@@@@    
    @@@@    @@@@  @@@@  @@@@@@@@@@@@  @@    @@@@@@@@  @@@@    @@  @@          
  @@              @@@@  @@  @@  @@@@@@  @@  @@    @@  @@@@  @@  @@@@@@@@@@    
  @@@@    @@@@@@@@@@      @@@@  @@@@@@@@@@  @@  @@@@  @@@@  @@@@@@    @@  @@  
        @@      @@@@  @@    @@@@@@  @@    @@@@@@@@    @@@@@@    @@@@@@@@@@    
    @@@@@@@@  @@    @@          @@  @@    @@@@  @@@@@@@@@@  @@@@              
  @@      @@@@      @@@@  @@  @@@@@@@@@@  @@@@    @@  @@        @@    @@@@    
            @@@@  @@@@@@@@  @@@@  @@@@@@@@@@@@  @@      @@  @@@@    @@@@@@@@  
            @@    @@@@@@  @@    @@            @@@@@@  @@@@@@      @@    @@    
    @@  @@  @@@@@@@@@@  @@@@@@@@@@    @@      @@@@      @@  @@    @@@@@@      
  @@      @@        @@  @@  @@  @@@@@@      @@@@  @@      @@@@@@      @@@@    
  @@@@@@  @@  @@    @@    @@@@  @@@@@@@@    @@@@@@@@  @@    @@@@      @@@@@@  
  @@@@@@  @@    @@    @@    @@@@@@  @@    @@    @@  @@  @@@@      @@    @@    
        @@@@  @@@@@@@@          @@@@@@    @@    @@@@  @@@@@@@@@@@@@@  @@      
            @@  @@        @@  @@@@@@@@      @@@@@@    @@        @@@@  @@@@    
  @@@@    @@@@@@        @@  @@@@  @@@@@@@@  @@  @@@@  @@@@@@@@@@@@@@@@@@      
                  @@      @@    @@        @@  @@@@    @@  @@      @@          
  @@@@@@@@@@@@@@    @@  @@@@@@@@@@        @@  @@@@@@@@@@  @@  @@  @@          
  @@          @@  @@  @@@@  @@  @@  @@@@    @@    @@  @@@@@@      @@  @@  @@  
  @@  @@@@@@  @@  @@      @@@@    @@@@  @@  @@@@  @@      @@@@@@@@@@@@@@@@@@  
  @@  @@@@@@  @@            @@@@@@    @@  @@    @@    @@@@  @@@@@@      @@@@  
  @@  @@@@@@  @@      @@        @@@@@@@@    @@@@@@@@  @@@@  @@@@@@            
  @@          @@  @@  @@  @@  @@    @@  @@  @@    @@    @@    @@      @@@@    
  @@@@@@@@@@@@@@  @@@@@@@@  @@@@    @@  @@@@@@@@@@@@    @@    @@@@@@@@@@@@@@  
                                                                              
""")
    }
    
    func testBorderless() throws {
        try expect(QRCode("https://github.com/ApolloZhu", withBorder: false),
               withFill: "MM", andPatch: "  ",
               toMatch: """
MMMMMMMMMMMMMM        MMMM  MM  MM  MMMMMM  MM  MM  MMMMMMMMMMMMMM
MM          MM    MM  MMMMMMMM    MM    MMMMMM  MM  MM          MM
MM  MMMMMM  MM  MMMM  MM  MMMMMMMM  MMMMMMMMMMMMMM  MM  MMMMMM  MM
MM  MMMMMM  MM  MM  MM        MM  MM  MM  MM  MM    MM  MMMMMM  MM
MM  MMMMMM  MM      MM  MMMM  MMMMMMMMMMMM    MMMM  MM  MMMMMM  MM
MM          MM    MMMM    MM    MM  MMMM      MM    MM          MM
MMMMMMMMMMMMMM  MM  MM  MM  MM  MM  MM  MM  MM  MM  MMMMMMMMMMMMMM
                  MM  MMMM    MM  MM            MM                
      MMMM  MMMM  MMMM    MM  MM    MMMMMM      MM        MMMM    
      MM  MM    MMMMMMMMMM  MMMMMM  MMMMMMMMMMMM  MM  MMMMMM      
  MMMM      MMMMMMMM  MM    MM  MM  MMMM    MMMMMM    MM    MMMMMM
MMMM  MM      MM  MM          MMMMMM  MMMMMMMMMM      MMMMMMMMMMMM
MM  MMMMMM  MMMM    MM        MM  MM      MM    MM  MMMMMMMM    MM
  MM          MMMMMM  MM      MMMM    MM  MM  MMMM    MMMM    MM  
MMMM        MMMM  MM  MM  MM                    MMMM  MM    MM    
MMMM  MM          MM  MM    MM  MM    MM      MMMM  MMMM  MMMM  MM
MMMMMM      MMMMMMMM  MM      MM      MMMM    MM  MMMM  MM    MM  
    MMMM  MM    MM  MM  MMMM  MMMM    MMMM  MM  MM  MMMMMMMM    MM
MMMM      MMMM    MM  MM  MMMM  MMMMMM      MMMM  MMMM  MMMMMM  MM
MM    MM      MMMM    MMMMMMMMMM  MM  MMMM  MMMMMM  MM    MMMMMM  
MM      MMMMMMMM    MMMM        MMMMMM  MM      MMMM  MM  MM  MMMM
MM    MM  MM      MMMM  MMMM  MMMM    MM  MMMM    MMMMMMMM        
MM        MMMM  MMMM    MM    MMMM    MM    MM  MM  MMMM    MMMMMM
MM  MM  MMMM    MMMM  MM      MM                      MMMM  MMMMMM
MMMMMMMMMMMMMM  MMMM      MM  MMMM  MM  MMMM    MMMMMMMMMM        
                MMMMMMMMMMMMMM      MM  MM  MM  MM      MMMM  MM  
MMMMMMMMMMMMMM  MMMM    MMMM  MM  MMMMMMMMMMMMMMMM  MM  MMMM      
MM          MM    MMMM    MMMM        MMMM    MMMM      MMMMMMMM  
MM  MMMMMM  MM  MMMM  MM      MMMM  MM  MMMM  MMMMMMMMMMMMMMMMMM  
MM  MMMMMM  MM  MM      MMMM      MMMMMM  MM      MM  MM    MMMM  
MM  MMMMMM  MM    MM  MM  MMMMMM  MM  MM    MM          MM  MMMMMM
MM          MM    MMMM              MM      MM      MM      MMMMMM
MMMMMMMMMMMMMM    MM  MMMM  MMMMMM  MMMM      MMMM      MM  MM    
""")
    }


    func testEFQRCode() throws {
        try expect(QRCode("https://github.com/EyreFree/EFQRCode"),
             withFill: "WW", andPatch: "  ",
             toMatch: """
                                                                              
  WWWWWWWWWWWWWW  WW                WWWW  WW          WWWWWW  WWWWWWWWWWWWWW  
  WW          WW  WW  WW  WWWWWWWWWWWWWW  WWWWWW      WWWW    WW          WW  
  WW  WWWWWW  WW    WW  WW  WWWW  WW        WWWW  WW  WW      WW  WWWWWW  WW  
  WW  WWWWWW  WW  WW    WWWW  WWWW  WW    WW  WW    WWWW      WW  WWWWWW  WW  
  WW  WWWWWW  WW  WWWW  WW        WW            WWWW  WWWW    WW  WWWWWW  WW  
  WW          WW  WWWWWW  WW      WWWWWWWW  WW  WW      WWWW  WW          WW  
  WWWWWWWWWWWWWW  WW  WW  WW  WW  WW  WW  WW  WW  WW  WW  WW  WWWWWWWWWWWWWW  
                      WW    WWWWWW  WW    WWWWWW    WW                        
        WW    WW    WW      WWWWWW            WWWWWW  WWWW      WWWWWW  WWWW  
  WWWW                WW  WWWWWWWW    WWWW  WW  WWWW    WW  WW    WW  WWWWWW  
  WW    WWWWWWWWWWWWWW  WW  WW    WWWWWWWWWW  WW  WW      WW  WWWW  WWWWWWWW  
  WWWW  WWWWWW    WW    WW    WW      WW      WW  WWWW  WW                WW  
    WWWWWWWWWWWWWWWW  WWWWWWWWWW              WW  WWWW    WWWWWW          WW  
  WWWW  WW  WW        WW  WWWWWW    WWWW  WWWWWW  WWWW  WW    WWWW  WW  WWWW  
  WWWW      WWWWWWWW  WW          WW          WW  WWWWWW          WW  WW  WW  
    WWWWWWWW    WW  WWWW    WW      WW    WWWWWWWW  WWWW  WWWWWWWW      WW    
    WWWW  WWWWWWWWWWWWWW  WWWWWWWWWW  WWWW  WWWW    WW  WW  WWWWWW  WWWWWWWW  
          WW        WW              WWWW    WWWWWWWWWWWW  WW  WWWWWWWWWW  WW  
  WWWWWWWWWW  WWWWWWWW        WWWWWW    WWWWWWWW  WWWW      WWWW      WWWWWW  
  WW  WWWWWWWW      WWWW  WW  WWWWWWWWWWWW  WW  WWWW                  WWWW    
  WWWWWW      WWWWWWWWWWWW  WWWWWWWW  WW              WWWWWW  WWWWWWWW    WW  
    WW      WW  WWWWWWWWWW    WW      WWWW  WW  WWWWWWWW    WWWW        WWWW  
    WWWWWW    WW      WW    WWWW  WWWWWW        WW  WWWW      WWWWWWWW  WWWW  
    WW    WW        WW    WW  WW  WW    WW    WW  WWWW      WW    WW    WWWW  
      WWWWWWWWWW  WWWW  WW      WW            WW      WWWWWW  WW  WW  WW  WW  
          WWWW  WWWW  WWWWWWWW    WWWW    WW  WWWW    WWWW            WW  WW  
  WW  WW  WWWWWW        WWWW  WWWW    WW  WWWW  WW  WWWWWWWWWWWWWW    WW  WW  
    WW  WW  WW    WW        WW    WWWW      WWWWWW  WWWW  WW  WW              
  WWWW  WW    WW    WWWW  WWWW    WW        WW    WW    WWWWWWWWWWWW  WW      
                  WW    WW  WW  WW        WW  WW  WWWWWWWWWW      WW    WWWW  
  WWWWWWWWWWWWWW    WW    WW  WWWWWWWWWWWWWWWWWW  WW    WWWW  WW  WW  WWWWWW  
  WW          WW    WW          WW  WW    WW  WW      WWWWWW      WW  WW      
  WW  WWWWWW  WW      WW      WWWW    WW  WW  WWWWWWWWWW  WWWWWWWWWWWW  WW    
  WW  WWWWWW  WW  WW      WWWWWW    WWWWWW  WW  WWWWWWWW    WW    WW    WWWW  
  WW  WWWWWW  WW      WW    WWWW  WW  WWWW      WWWWWWWWWW  WW    WWWW    WW  
  WW          WW    WW    WWWW  WW  WWWW    WW  WWWWWW  WWWW    WW            
  WWWWWWWWWWWWWW    WW  WW    WWWWWW  WW  WW    WW      WWWWWW  WWWW    WWWW  
                                                                              
""")
    }

    func testEmpty() throws {
        try expect(QRCode("", errorCorrectLevel: .L),
             withFill: "XX", andPatch: "  ",
             toMatch: """
                                              
  XXXXXXXXXXXXXX    XX    XX  XXXXXXXXXXXXXX  
  XX          XX  XX    XX    XX          XX  
  XX  XXXXXX  XX    XX        XX  XXXXXX  XX  
  XX  XXXXXX  XX  XX    XX    XX  XXXXXX  XX  
  XX  XXXXXX  XX      XXXXXX  XX  XXXXXX  XX  
  XX          XX  XXXXXX  XX  XX          XX  
  XXXXXXXXXXXXXX  XX  XX  XX  XXXXXXXXXXXXXX  
                      XXXXXX                  
  XXXXXXXXXX  XXXXXXXX    XXXX  XX  XX  XX    
    XXXX        XXXX  XX  XX    XX    XX      
        XX    XX  XX  XXXX  XX    XXXXXXXXXX  
  XX      XX        XXXX        XXXX  XX  XX  
  XXXXXX    XXXXXXXX    XX  XX    XXXXXXXXXX  
                  XXXXXXXXXXXXXX    XX        
  XXXXXXXXXXXXXX  XXXXXX  XX  XXXX            
  XX          XX    XXXXXXXXXXXX    XX        
  XX  XXXXXX  XX  XXXXXX  XX    XX    XX      
  XX  XXXXXX  XX  XXXX    XX    XX    XX      
  XX  XXXXXX  XX  XXXX  XX  XX    XXXXXX      
  XX          XX  XXXX          XXXX  XX      
  XXXXXXXXXXXXXX  XX  XXXX  XX    XXXXXXXX    
                                              
""")
    }

    func testStressWithPi() throws {
        let content = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
        try expect(QRCode(content, errorCorrectLevel: .M),
               withFill: "%%", andPatch: "  ",
               toMatch: """
                                                                                                                                                                                                                                                      
  %%%%%%%%%%%%%%  %%%%%%  %%%%%%%%%%%%  %%%%%%%%        %%%%%%  %%  %%    %%%%  %%%%              %%%%%%      %%    %%      %%%%%%  %%%%    %%%%%%                  %%  %%%%%%  %%  %%%%%%        %%  %%    %%        %%  %%  %%%%    %%%%%%%%%%%%%%  
  %%          %%  %%    %%    %%%%%%%%  %%    %%  %%    %%          %%    %%      %%%%          %%    %%%%%%%%  %%        %%  %%%%%%%%  %%  %%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%  %%  %%          %%  
  %%  %%%%%%  %%      %%      %%%%    %%                  %%%%          %%    %%%%  %%    %%%%%%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%    %%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%%%      %%  %%%%%%%%  %%          %%%%  %%  %%%%%%  %%  
  %%  %%%%%%  %%  %%%%%%  %%%%%%  %%  %%          %%          %%%%    %%%%%%    %%    %%%%          %%  %%      %%      %%  %%    %%%%%%    %%    %%      %%      %%%%  %%  %%%%  %%    %%  %%%%  %%        %%%%%%%%    %%  %%%%%%%%  %%  %%%%%%  %%  
  %%  %%%%%%  %%    %%    %%%%  %%      %%    %%  %%    %%%%%%%%%%%%    %%%%%%%%  %%%%  %%        %%  %%    %%    %%%%%%%%%%  %%            %%%%    %%%%    %%    %%  %%%%%%%%%%%%%%      %%%%  %%%%      %%%%  %%%%            %%    %%  %%%%%%  %%  
  %%          %%    %%%%%%%%%%%%    %%  %%  %%    %%  %%  %%      %%      %%%%%%  %%      %%  %%%%%%%%  %%        %%      %%%%  %%        %%  %%%%%%%%  %%        %%  %%  %%      %%      %%  %%%%%%%%  %%        %%  %%%%%%%%%%%%    %%          %%  
  %%%%%%%%%%%%%%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%  %%%%%%%%%%%%%%  
                  %%            %%  %%%%  %%%%%%%%  %%%%  %%      %%    %%%%  %%  %%    %%  %%%%%%  %%        %%%%%%      %%%%        %%  %%%%%%%%  %%        %%  %%%%%%  %%      %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%%%                  
  %%  %%%%  %%%%%%  %%      %%%%%%%%  %%  %%  %%%%%%      %%%%%%%%%%%%%%    %%  %%      %%%%  %%%%%%%%  %%%%%%    %%%%%%%%%%%%    %%%%  %%%%  %%%%  %%  %%      %%%%    %%%%%%%%%%%%    %%          %%  %%      %%  %%%%          %%  %%    %%  %%%%  
  %%        %%      %%    %%%%%%  %%    %%%%  %%  %%%%  %%%%%%  %%  %%%%%%      %%%%%%%%  %%    %%%%%%        %%        %%%%    %%%%        %%%%%%%%  %%%%  %%%%          %%  %%    %%%%            %%%%%%  %%    %%%%%%  %%%%%%        %%%%    %%    
      %%%%    %%  %%%%%%  %%      %%%%%%%%  %%%%      %%  %%%%    %%%%%%    %%  %%    %%%%        %%  %%%%%%%%    %%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%      %%  %%  %%%%%%  %%        %%  %%%%%%%%  %%        %%  %%  %%      %%    %%    
      %%        %%  %%    %%      %%  %%%%      %%  %%    %%  %%%%%%%%        %%%%%%  %%    %%        %%  %%%%%%    %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%      %%    %%%%%%%%  %%        %%  %%%%%%%%  %%        %%%%            %%  %%  
      %%  %%%%%%      %%%%  %%    %%  %%%%  %%%%%%%%      %%  %%    %%%%  %%%%%%%%    %%  %%%%  %%%%          %%%%%%    %%%%    %%              %%  %%  %%    %%%%  %%  %%        %%  %%%%        %%%%  %%%%  %%  %%%%  %%%%%%  %%  %%  %%    %%%%%%  
  %%  %%          %%      %%      %%%%%%  %%    %%  %%  %%%%%%%%%%  %%%%%%  %%%%  %%%%      %%        %%    %%    %%%%  %%        %%            %%    %%%%    %%%%%%%%  %%  %%  %%  %%  %%%%    %%  %%%%%%  %%%%  %%  %%        %%%%    %%  %%    %%  
  %%    %%%%%%%%    %%    %%  %%    %%%%      %%  %%          %%  %%%%    %%  %%  %%%%  %%    %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%    %%  %%        %%  %%%%%%%%  %%        %%  %%%%  %%    %%  %%%%    %%      
            %%    %%  %%    %%      %%    %%  %%%%  %%%%  %%    %%    %%%%  %%%%                  %%%%%%%%  %%  %%    %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%%%%%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%  %%  %%%%  %%        
    %%%%%%    %%  %%  %%%%%%%%    %%%%%%        %%%%%%%%          %%%%  %%  %%%%%%    %%  %%%%%%%%  %%%%    %%  %%          %%%%    %%    %%        %%%%%%  %%    %%  %%%%    %%%%  %%  %%%%  %%  %%  %%%%  %%  %%%%          %%      %%%%%%%%%%%%    
      %%    %%    %%%%%%    %%%%  %%%%%%%%%%%%          %%%%%%%%  %%  %%%%  %%%%  %%  %%%%        %%  %%%%%%%%  %%    %%%%  %%    %%%%%%%%          %%%%        %%%%%%%%%%%%%%%%    %%%%%%    %%    %%                      %%%%    %%    %%  %%%%%%  
    %%%%  %%%%%%  %%    %%        %%  %%%%  %%    %%      %%    %%%%%%        %%    %%%%  %%  %%%%        %%  %%%%%%%%  %%            %%%%%%%%  %%        %%  %%%%%%%%            %%  %%%%%%%%  %%        %%  %%%%%%%%  %%                        %%  
  %%    %%%%%%  %%%%%%  %%%%%%%%    %%    %%  %%      %%%%%%    %%%%%%    %%    %%%%  %%%%%%    %%  %%          %%%%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%  %%%%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%%%%%    %%    %%%%  
    %%%%    %%%%  %%%%  %%  %%%%  %%%%      %%  %%    %%    %%  %%    %%%%          %%%%%%%%  %%%%      %%%%%%%%  %%%%%%%%%%%%  %%%%    %%%%%%%%          %%      %%%%%%%%%%      %%%%    %%  %%    %%    %%%%%%%%%%    %%  %%%%  %%%%%%    %%        
  %%  %%%%%%%%  %%%%            %%%%  %%%%%%  %%  %%%%%%%%    %%%%%%%%      %%%%    %%%%    %%%%%%%%  %%              %%  %%%%  %%    %%%%  %%%%%%%%%%%%    %%%%    %%%%  %%%%  %%%%          %%  %%%%  %%%%        %%    %%%%      %%%%%%%%%%  %%    
      %%  %%  %%          %%    %%%%  %%    %%%%%%  %%        %%%%%%  %%  %%    %%            %%  %%  %%%%%%  %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%            %%%%%%%%  %%        %%  %%%%%%  %%%%        %%  %%%%        %%%%%%%%    
  %%%%  %%  %%    %%  %%%%%%  %%  %%%%  %%  %%  %%  %%    %%        %%  %%%%      %%%%  %%%%%%%%      %%  %%    %%%%%%        %%  %%%%%%%%  %%        %%  %%%%  %%  %%    %%  %%  %%%%%%%%  %%        %%  %%    %%  %%        %%%%      %%%%  %%%%%%  
    %%  %%  %%%%%%%%%%            %%  %%  %%    %%  %%    %%  %%%%%%  %%    %%  %%  %%    %%  %%%%%%%%        %%%%%%%%%%%%%%    %%      %%%%    %%%%    %%  %%%%%%  %%%%%%          %%%%%%      %%%%%%  %%  %%%%    %%%%%%%%    %%  %%        %%  %%  
    %%    %%      %%    %%%%%%  %%      %%%%      %%    %%    %%        %%  %%%%  %%%%      %%%%%%%%%%%%%%        %%    %%%%%%    %%%%  %%%%  %%%%%%%%      %%%%    %%  %%  %%%%      %%    %%%%%%%%      %%%%%%%%%%%%  %%%%            %%  %%  %%%%  
  %%%%%%%%%%  %%%%%%  %%%%%%      %%%%%%    %%  %%%%  %%%%%%      %%                %%%%%%%%    %%%%%%  %%            %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%    %%  %%%%  %%%%%%%%  
    %%  %%  %%        %%%%  %%%%  %%  %%  %%  %%  %%            %%      %%%%            %%%%%%    %%%%%%%%  %%    %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%%%%%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%  %%  %%  %%%%  %%    
    %%%%%%%%%%%%%%%%  %%      %%%%%%%%%%%%    %%%%%%  %%%%%%%%%%%%%%%%        %%%%      %%  %%%%            %%  %%%%%%%%%%%%%%%%    %%%%  %%%%  %%%%        %%    %%      %%%%%%%%%%        %%  %%    %%%%  %%  %%%%%%  %%%%  %%  %%%%%%%%%%%%%%%%    
      %%%%%%      %%%%%%    %%    %%    %%%%%%%%  %%%%%%%%%%      %%%%  %%  %%%%  %%%%%%%%      %%  %%    %%  %%  %%      %%  %%        %%%%  %%        %%%%%%  %%%%    %%%%      %%%%      %%  %%    %%      %%      %%      %%  %%      %%  %%      
  %%      %%  %%  %%  %%  %%%%%%      %%      %%%%%%%%%%  %%  %%  %%%%      %%  %%      %%      %%        %%  %%  %%  %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%    %%  %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%      %%%%  %%  %%  %%%%    
  %%      %%      %%%%%%  %%    %%        %%  %%  %%%%%%%%%%      %%%%          %%%%  %%%%      %%  %%        %%  %%      %%%%        %%  %%%%%%%%  %%        %%  %%%%%%%%%%      %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%    %%      %%    %%%%  
          %%%%%%%%%%    %%  %%%%%%%%%%  %%%%%%%%%%        %%%%%%%%%%  %%  %%%%  %%%%%%%%  %%  %%%%%%%%  %%    %%  %%%%%%%%%%    %%%%          %%%%  %%  %%      %%%%  %%  %%%%%%%%%%%%  %%%%        %%  %%  %%    %%  %%%%%%%%    %%%%%%%%%%%%  %%%%  
    %%            %%%%            %%%%%%%%%%  %%%%%%            %%%%      %%%%  %%%%%%%%    %%  %%%%        %%%%    %%%%    %%%%    %%%%  %%  %%  %%%%%%%%              %%  %%              %%  %%%%%%%%%%  %%      %%%%  %%%%    %%%%      %%  %%    
  %%%%  %%%%%%%%%%  %%    %%          %%%%%%    %%    %%    %%%%    %%%%%%%%  %%%%%%%%%%      %%  %%  %%    %%  %%            %%%%%%%%  %%        %%  %%%%  %%  %%      %%%%  %%  %%%%  %%        %%  %%    %%  %%        %%  %%%%      %%  %%%%%%    
    %%%%%%%%          %%          %%  %%%%%%    %%  %%  %%%%%%%%%%  %%    %%            %%            %%%%  %%%%      %%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%  %%  %%  %%%%%%  %%        %%%%  %%%%%%  %%        %%  %%%%%%%%    %%  %%  
          %%  %%%%  %%%%%%%%%%%%  %%%%    %%      %%    %%%%  %%%%%%%%  %%%%%%%%%%%%  %%%%    %%%%%%%%  %%%%  %%      %%  %%          %%%%  %%  %%%%%%        %%%%  %%      %%%%%%  %%  %%  %%  %%      %%%%%%%%  %%    %%  %%    %%  %%      %%  %%  
  %%    %%%%    %%  %%    %%%%  %%%%  %%    %%%%%%%%%%%%    %%%%%%%%%%%%%%  %%%%%%%%  %%  %%  %%%%%%  %%%%%%      %%  %%%%              %%%%%%      %%%%    %%%%%%%%  %%%%      %%  %%%%  %%  %%    %%%%%%%%%%    %%%%%%%%        %%  %%%%%%  %%  %%  
  %%%%%%  %%%%%%    %%    %%%%  %%  %%%%%%%%%%      %%  %%    %%          %%%%%%    %%%%%%%%%%  %%%%%%  %%%%      %%%%%%    %%  %%        %%  %%%%%%%%  %%        %%  %%  %%      %%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%%%      %%%%%%      
      %%    %%      %%%%  %%%%%%%%%%%%%%  %%      %%%%%%%%%%%%  %%    %%            %%    %%%%%%  %%%%%%%%  %%  %%  %%  %%  %%%%%%  %%%%      %%  %%%%%%%%  %%        %%%%%%      %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%%%%%      %%        
  %%%%        %%%%        %%%%%%  %%      %%%%%%%%  %%%%    %%  %%  %%%%  %%  %%            %%%%%%%%  %%%%  %%      %%%%%%  %%%%  %%%%%%  %%          %%  %%%%  %%  %%  %%%%%%      %%    %%%%    %%%%%%%%      %%%%      %%  %%%%  %%  %%  %%%%      
  %%  %%%%  %%  %%%%  %%%%  %%%%%%%%%%  %%      %%%%      %%%%    %%  %%      %%  %%%%    %%%%%%%%  %%%%  %%  %%%%%%%%%%        %%%%%%  %%  %%  %%        %%%%                      %%%%%%%%                %%  %%%%  %%%%          %%%%%%  %%%%%%%%  
  %%  %%    %%%%%%    %%  %%%%%%%%    %%%%    %%  %%  %%%%%%  %%  %%%%    %%%%%%%%%%%%    %%    %%        %%  %%  %%  %%%%%%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%            %%%%%%%%  %%        %%  %%%%%%%%  %%            %%%%%%%%    %%  
  %%%%%%%%  %%  %%%%%%%%  %%%%  %%%%%%%%%%%%    %%%%%%      %%%%%%    %%    %%%%  %%  %%%%%%    %%  %%        %%%%%%      %%%%        %%  %%%%%%%%  %%        %%  %%%%%%      %%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%%%    %%    %%    %%%%  
          %%  %%%%%%%%%%%%  %%%%%%    %%%%    %%    %%  %%%%%%%%%%%%  %%            %%      %%%%%%      %%    %%%%%%%%          %%%%    %%      %%%%%%  %%%%%%      %%%%  %%  %%  %%%%  %%        %%              %%    %%      %%%%      %%%%  %%    
            %%  %%%%%%      %%%%          %%%%      %%%%%%    %%%%%%    %%%%%%%%  %%%%%%    %%    %%%%%%%%    %%%%  %%  %%%%  %%%%%%              %%%%%%    %%%%    %%  %%  %%      %%%%    %%  %%%%        %%      %%          %%%%%%          %%    
      %%%%    %%%%%%    %%    %%%%  %%%%  %%%%%%        %%  %%  %%  %%  %%%%%%%%          %%      %%  %%%%%%%%      %%        %%%%%%%%  %%        %%  %%%%%%%%  %%      %%%%  %%    %%  %%        %%  %%%%%%%%  %%        %%  %%%%  %%  %%  %%%%%%    
    %%  %%%%    %%    %%  %%        %%  %%%%                %%  %%  %%  %%    %%      %%              %%  %%%%%%      %%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%  %%  %%  %%%%%%  %%        %%  %%%%%%%%  %%        %%        %%    %%  %%  
  %%%%    %%%%%%      %%  %%  %%%%%%%%%%      %%%%    %%    %%  %%    %%%%%%  %%    %%%%  %%%%%%%%%%    %%    %%          %%  %%%%        %%%%%%%%        %%  %%    %%    %%%%%%%%              %%%%          %%    %%  %%  %%    %%  %%%%    %%  %%  
  %%  %%        %%      %%  %%    %%            %%%%%%    %%%%%%%%%%        %%%%  %%  %%  %%%%%%%%%%      %%  %%%%  %%%%%%    %%  %%    %%%%%%      %%%%%%  %%%%%%%%%%    %%  %%  %%%%  %%%%    %%  %%        %%      %%    %%%%  %%  %%          %%  
  %%  %%%%%%%%%%    %%        %%%%      %%  %%%%  %%%%%%%%%%%%%%    %%        %%    %%%%%%%%  %%%%%%%%  %%      %%%%    %%  %%  %%        %%  %%%%%%%%  %%        %%  %%  %%    %%%%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%%%%%  %%%%          
  %%%%  %%%%    %%%%  %%%%      %%%%%%  %%    %%  %%%%%%  %%      %%  %%%%      %%%%%%%%  %%%%    %%%%%%%%  %%  %%    %%%%  %%%%%%  %%        %%  %%%%%%%%  %%        %%%%%%      %%%%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%      %%  %%%%  
        %%  %%%%  %%%%%%            %%      %%%%    %%  %%%%%%%%  %%        %%  %%        %%%%%%%%%%%%  %%        %%    %%      %%  %%  %%            %%%%%%%%    %%    %%  %%      %%  %%%%  %%%%    %%    %%  %%%%%%  %%    %%%%  %%  %%  %%%%%%%%  
  %%%%    %%%%  %%%%%%%%  %%  %%    %%    %%%%%%    %%%%%%%%  %%      %%%%  %%%%      %%    %%%%%%  %%%%%%%%  %%%%%%    %%          %%            %%    %%%%%%  %%%%  %%%%  %%%%%%%%%%  %%%%%%%%  %%%%%%      %%%%%%%%              %%%%%%      %%%%  
    %%%%%%    %%%%  %%%%%%  %%  %%  %%%%%%  %%%%%%%%    %%  %%%%      %%          %%  %%  %%  %%%%  %%%%  %%  %%  %%%%            %%  %%    %%  %%        %%  %%%%%%%%                %%%%  %%  %%        %%  %%%%%%%%  %%            %%    %%    %%  
    %%  %%  %%                %%      %%    %%    %%%%  %%  %%%%%%%%%%%%    %%  %%%%%%          %%    %%      %%%%%%      %%%%        %%%%  %%%%%%  %%        %%  %%%%%%      %%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%    %%  %%%%            
      %%  %%%%%%%%%%        %%  %%%%%%%%    %%%%%%  %%    %%%%%%%%%%%%%%%%    %%%%%%%%%%%%  %%%%%%%%%%      %%  %%%%%%%%%%%%%%    %%  %%%%%%%%%%%%    %%  %%    %%  %%%%  %%%%%%%%%%  %%      %%%%  %%    %%          %%%%%%%%  %%%%%%%%%%%%%%    %%  
  %%%%    %%      %%        %%  %%%%%%%%    %%  %%      %%%%      %%%%          %%%%  %%  %%      %%%%      %%  %%%%      %%%%%%    %%%%%%%%  %%%%%%  %%    %%%%        %%%%      %%%%%%        %%%%%%  %%%%  %%  %%      %%  %%  %%      %%    %%    
    %%  %%%%  %%  %%  %%%%  %%        %%  %%%%      %%  %%%%  %%  %%  %%%%  %%  %%%%      %%%%    %%  %%%%%%%%    %%  %%  %%  %%%%%%%%  %%        %%%%  %%%%%%  %%      %%%%  %%  %%%%  %%        %%  %%%%%%%%  %%        %%  %%  %%  %%  %%%%  %%    
  %%%%%%%%%%      %%    %%  %%  %%%%%%%%%%%%  %%  %%  %%%%%%      %%%%%%%%%%  %%  %%%%%%  %%%%%%          %%%%%%%%%%      %%  %%  %%%%%%%%  %%      %%    %%%%%%%%  %%  %%%%      %%%%%%%%  %%            %%%%%%%%  %%        %%%%%%      %%  %%%%    
  %%%%%%%%%%%%%%%%%%  %%  %%  %%  %%      %%%%    %%    %%%%%%%%%%%%%%      %%%%%%%%%%      %%  %%%%    %%    %%  %%%%%%%%%%    %%%%  %%          %%        %%%%    %%    %%%%%%%%%%  %%  %%        %%        %%  %%%%            %%%%%%%%%%  %%      
  %%%%%%%%%%%%    %%  %%    %%%%        %%%%%%%%  %%%%      %%%%%%        %%  %%%%%%%%    %%%%  %%  %%%%  %%%%  %%  %%%%%%  %%  %%  %%%%  %%        %%      %%%%    %%    %%%%      %%  %%%%    %%  %%%%    %%  %%%%%%%%            %%            %%  
      %%%%%%%%%%  %%%%%%%%%%      %%%%    %%%%  %%%%  %%%%%%%%  %%%%%%    %%%%  %%%%%%%%%%%%    %%%%%%  %%      %%          %%  %%        %%  %%%%%%%%  %%        %%  %%    %%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%%%%%%%  %%          
          %%%%      %%%%%%  %%%%    %%  %%            %%  %%%%  %%%%%%%%%%%%%%      %%    %%  %%  %%%%%%%%  %%  %%  %%      %%%%%%  %%        %%  %%%%%%%%  %%        %%      %%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%      %%%%%%  %%%%  
  %%%%  %%%%%%%%  %%  %%    %%  %%%%    %%%%    %%%%%%    %%%%    %%  %%%%  %%  %%        %%%%%%%%    %%%%        %%        %%%%        %%      %%%%  %%  %%%%%%  %%%%        %%%%%%%%  %%      %%  %%%%  %%      %%      %%%%%%    %%    %%%%%%%%    
    %%%%              %%  %%  %%%%      %%      %%  %%    %%      %%  %%%%  %%      %%%%  %%%%    %%  %%  %%      %%%%          %%%%%%%%    %%%%    %%    %%%%  %%%%    %%%%  %%  %%    %%            %%  %%  %%%%%%  %%%%    %%%%      %%%%%%%%%%%%  
    %%  %%%%  %%%%        %%%%%%%%%%%%%%%%    %%%%  %%%%%%  %%      %%      %%%%          %%%%  %%        %%  %%        %%%%      %%  %%%%%%%%  %%        %%  %%%%%%%%    %%    %%    %%%%%%%%  %%        %%  %%%%%%%%  %%      %%%%%%  %%        %%  
  %%%%  %%%%%%      %%%%      %%%%  %%%%        %%  %%    %%    %%%%%%        %%        %%      %%  %%        %%  %%  %%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%%%  %%%%    %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%%%%%  %%            
    %%%%%%%%%%%%  %%%%%%            %%%%%%%%%%%%      %%%%%%%%%%    %%    %%                  %%    %%    %%    %%    %%    %%%%  %%  %%        %%        %%%%  %%%%%%%%    %%  %%                %%%%    %%    %%%%%%%%%%      %%  %%  %%  %%    %%  
  %%  %%        %%%%%%%%    %%  %%    %%              %%    %%%%          %%  %%  %%%%      %%%%%%%%    %%    %%%%%%  %%%%  %%  %%%%  %%  %%    %%%%  %%      %%        %%  %%%%%%                %%  %%      %%          %%    %%    %%%%%%%%%%%%    
        %%%%%%%%%%      %%          %%      %%    %%  %%%%%%%%  %%      %%%%%%%%        %%  %%    %%  %%%%%%%%    %%    %%%%  %%%%%%%%  %%        %%  %%%%%%%%    %%    %%  %%%%%%  %%  %%        %%  %%%%%%%%  %%%%      %%  %%        %%%%    %%    
  %%%%  %%%%%%  %%  %%        %%    %%%%  %%  %%%%%%%%%%%%%%    %%  %%    %%%%%%  %%  %%%%%%%%%%      %%  %%%%%%%%%%    %%%%%%    %%%%%%%%  %%        %%  %%%%%%  %%%%  %%%%  %%%%%%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%  %%  %%%%%%  
  %%  %%  %%%%%%%%%%  %%%%%%%%  %%  %%%%%%      %%    %%%%%%          %%%%%%  %%        %%    %%%%%%%%      %%%%%%  %%  %%  %%%%      %%        %%%%      %%  %%  %%    %%%%      %%      %%%%%%  %%    %%  %%%%%%  %%    %%      %%          %%%%%%  
    %%%%  %%%%  %%%%%%      %%        %%%%    %%  %%%%%%                %%          %%%%%%%%%%      %%%%  %%%%  %%  %%%%%%          %%    %%%%      %%%%%%      %%  %%    %%%%      %%    %%%%  %%  %%%%  %%  %%  %%%%%%    %%%%    %%    %%      %%  
  %%    %%  %%%%      %%%%%%  %%  %%%%        %%%%%%        %%  %%      %%      %%%%        %%  %%%%%%  %%      %%  %%%%%%%%  %%%%        %%  %%%%%%%%  %%        %%  %%    %%            %%  %%%%%%%%  %%        %%  %%%%%%%%  %%%%%%%%%%%%          
  %%%%      %%          %%  %%%%%%          %%%%  %%  %%      %%%%      %%%%      %%%%%%    %%%%  %%%%%%%%  %%      %%%%%%%%    %%  %%        %%  %%%%%%%%  %%        %%%%%%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%    %%%%%%%%    %%  
    %%      %%%%  %%  %%%%        %%%%%%    %%%%%%%%      %%%%  %%  %%        %%%%%%  %%    %%      %%%%  %%%%%%%%%%      %%  %%%%      %%%%    %%  %%%%%%%%%%  %%%%    %%    %%%%%%        %%  %%%%  %%%%%%      %%%%%%    %%%%%%%%  %%  %%%%%%%%%%  
  %%  %%%%%%%%  %%        %%%%%%    %%%%%%%%%%%%%%    %%  %%%%%%%%  %%%%%%%%    %%    %%%%%%%%  %%    %%%%%%        %%      %%%%    %%        %%      %%%%%%  %%%%%%%%%%%%%%  %%  %%%%%%    %%%%      %%%%%%  %%%%      %%        %%      %%  %%%%%%  
  %%  %%%%%%  %%  %%  %%    %%%%      %%  %%%%%%        %%          %%    %%        %%      %%%%%%        %%  %%    %%    %%      %%  %%%%%%%%  %%        %%  %%%%%%%%    %%          %%%%%%%%  %%        %%  %%%%%%  %%%%          %%            %%  
      %%        %%    %%  %%  %%              %%%%%%            %%%%  %%  %%      %%  %%  %%%%%%%%  %%        %%%%%%%%%%    %%        %%  %%%%%%%%  %%        %%  %%%%  %%            %%  %%%%%%%%  %%        %%  %%    %%  %%  %%      %%      %%%%  
  %%%%%%  %%  %%        %%    %%%%%%%%                %%%%      %%  %%%%%%%%    %%%%%%%%%%%%    %%  %%  %%      %%    %%%%%%%%%%%%%%        %%%%  %%%%%%%%%%        %%%%%%  %%  %%  %%  %%%%%%%%%%              %%%%        %%%%%%      %%  %%%%      
    %%%%%%            %%%%  %%%%            %%        %%%%%%%%%%%%%%  %%  %%%%%%    %%  %%      %%%%        %%%%      %%  %%%%  %%%%%%%%  %%    %%%%    %%%%%%    %%%%%%%%  %%%%%%  %%  %%  %%%%  %%%%      %%%%%%          %%  %%    %%%%  %%%%%%    
  %%%%%%%%%%%%%%      %%        %%%%                            %%%%%%  %%%%    %%    %%      %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%      %%  %%%%  %%%%  %%        %%  %%%%%%%%  %%        %%  %%      %%  %%  %%%%    
  %%      %%%%    %%    %%%%%%  %%%%    %%%%    %%%%%%      %%  %%    %%  %%%%  %%%%%%  %%%%%%%%      %%  %%%%%%%%%%  %%%%    %%  %%%%%%%%  %%        %%  %%%%%%%%  %%          %%%%%%%%%%  %%        %%  %%%%%%%%  %%        %%          %%  %%  %%  
      %%  %%%%%%%%%%%%      %%    %%  %%  %%        %%  %%%%%%%%%%%%%%  %%  %%  %%  %%  %%%%  %%  %%%%      %%%%%%%%%%%%%%%%%%  %%    %%%%          %%        %%%%        %%%%%%%%%%        %%    %%%%    %%              %%      %%%%%%%%%%  %%%%%%  
  %%      %%      %%%%  %%            %%  %%  %%          %%      %%        %%      %%    %%  %%    %%%%  %%%%  %%%%      %%  %%    %%%%    %%%%    %%              %%%%%%%%      %%%%    %%  %%        %%          %%  %%%%    %%%%      %%  %%  %%  
    %%  %%%%  %%  %%%%%%  %%%%      %%  %%  %%  %%  %%    %%  %%  %%  %%%%%%  %%%%%%%%%%    %%  %%%%%%  %%        %%  %%  %%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%  %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%    %%  %%  %%%%%%      
    %%  %%%%      %%        %%%%%%    %%%%%%%%        %%  %%      %%%%  %%%%%%    %%%%%%%%%%  %%  %%%%%%%%  %%  %%%%      %%%%%%%%  %%        %%  %%%%%%%%  %%        %%%%%%      %%%%        %%  %%%%%%%%  %%        %%  %%%%%%%%%%      %%%%  %%    
  %%  %%%%%%%%%%%%%%  %%%%  %%%%  %%  %%  %%  %%    %%%%%%%%%%%%%%%%    %%%%%%%%  %%    %%%%%%  %%%%  %%%%%%      %%%%%%%%%%    %%%%            %%  %%%%%%  %%    %%    %%%%%%%%%%%%      %%%%  %%  %%%%%%        %%          %%%%%%%%%%%%%%%%%%%%    
  %%      %%%%    %%    %%    %%%%%%  %%%%%%%%    %%  %%  %%          %%        %%  %%%%%%    %%%%      %%%%%%%%%%    %%%%%%%%    %%              %%%%%%  %%%%  %%%%      %%%%  %%  %%%%%%  %%    %%%%%%    %%%%      %%  %%  %%    %%  %%  %%%%%%%%  
  %%%%        %%%%      %%%%%%  %%      %%%%%%%%%%  %%%%%%%%%%      %%  %%%%%%    %%%%%%  %%      %%      %%  %%      %%  %%      %%  %%%%%%%%  %%%%      %%  %%%%%%%%    %%%%%%%%    %%%%%%%%    %%      %%  %%%%%%%%  %%      %%%%  %%%%        %%  
  %%%%  %%  %%          %%%%        %%%%  %%    %%%%%%      %%      %%        %%%%  %%%%      %%  %%%%        %%%%      %%  %%        %%  %%%%%%%%  %%        %%  %%%%%%  %%    %%    %%  %%%%%%  %%%%        %%  %%%%%%%%  %%  %%    %%  %%    %%    
            %%%%  %%  %%  %%  %%%%%%%%%%  %%%%          %%  %%%%  %%      %%  %%    %%  %%        %%%%                %%        %%        %%  %%%%  %%  %%%%%%  %%  %%%%%%  %%    %%    %%  %%    %%      %%      %%%%%%%%        %%%%    %%%%    %%  
        %%%%          %%%%  %%  %%    %%  %%    %%%%  %%    %%    %%  %%    %%%%%%  %%    %%  %%%%      %%          %%  %%      %%  %%  %%        %%%%  %%%%  %%          %%      %%    %%  %%%%%%    %%        %%      %%%%      %%        %%  %%    
    %%%%%%%%  %%%%  %%%%%%  %%%%        %%%%%%%%    %%      %%%%%%%%%%%%  %%  %%  %%        %%%%      %%%%%%%%    %%%%%%%%    %%%%%%%%  %%        %%  %%%%%%%%  %%      %%  %%      %%  %%  %%%%  %%  %%%%%%%%  %%        %%  %%  %%%%        %%%%    
          %%%%    %%  %%%%%%%%%%  %%%%                    %%%%  %%%%  %%%%    %%    %%    %%%%%%      %%  %%%%%%%%%%  %%%%%%  %%  %%%%%%%%  %%%%      %%  %%%%%%%%  %%    %%        %%%%%%    %%      %%  %%%%%%%%  %%        %%%%%%%%%%%%    %%%%    
  %%%%%%      %%%%%%%%  %%%%  %%    %%%%%%%%%%%%%%%%%%      %%%%  %%  %%%%%%          %%  %%%%  %%%%%%  %%  %%%%%%  %%    %%%%      %%%%%%%%%%      %%        %%%%%%%%%%%%%%%%        %%  %%    %%      %%  %%%%    %%%%%%%%    %%%%  %%%%%%  %%%%%%  
        %%        %%  %%%%  %%  %%%%  %%%%%%%%        %%%%  %%%%%%%%%%%%  %%  %%%%%%  %%%%%%    %%    %%      %%          %%      %%%%    %%  %%    %%  %%      %%%%    %%    %%%%%%%%    %%%%%%    %%%%    %%%%%%%%    %%            %%  %%%%    %%  
  %%  %%  %%  %%    %%                %%  %%%%      %%%%%%%%%%%%        %%%%      %%      %%  %%%%%%%%  %%          %%      %%  %%        %%  %%%%%%%%  %%        %%  %%  %%  %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%      
      %%%%  %%    %%      %%%%  %%%%              %%  %%    %%%%%%%%      %%  %%%%      %%  %%    %%%%%%%%  %%    %%      %%%%%%%%  %%        %%  %%%%%%%%  %%        %%            %%        %%  %%%%%%%%  %%        %%  %%%%%%    %%      %%        
  %%  %%  %%  %%    %%    %%  %%%%  %%%%    %%%%  %%        %%%%%%          %%%%      %%  %%  %%      %%%%  %%  %%%%        %%%%%%%%%%  %%%%  %%      %%%%%%    %%%%        %%    %%%%%%%%  %%  %%  %%%%%%  %%%%%%%%%%        %%  %%    %%  %%%%      
      %%%%  %%    %%%%  %%  %%    %%%%  %%%%%%%%%%%%    %%%%%%    %%            %%%%%%    %%%%%%    %%%%  %%  %%%%%%  %%%%%%%%%%  %%          %%  %%%%%%%%%%    %%  %%%%  %%%%  %%  %%  %%    %%  %%                %%          %%%%  %%%%      %%%%  
    %%%%  %%%%%%      %%%%%%%%%%%%%%  %%%%  %%%%  %%%%%%%%  %%%%%%%%  %%    %%%%            %%%%%%        %%  %%%%    %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%%%%%    %%%%%%%%  %%        %%  %%%%%%%%  %%      %%%%  %%    %%    %%  
  %%%%    %%            %%%%  %%%%      %%  %%  %%  %%    %%%%%%  %%    %%%%%%    %%%%%%%%%%%%  %%  %%        %%        %%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%%%%%%%  %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%  %%    %%  %%          
  %%          %%                %%%%%%%%%%        %%%%%%%%%%    %%%%%%%%            %%%%%%%%  %%%%  %%      %%      %%%%  %%      %%  %%  %%%%%%            %%      %%%%%%    %%  %%%%  %%        %%    %%%%  %%  %%  %%%%  %%%%      %%  %%%%    %%  
  %%  %%%%      %%%%      %%    %%%%                    %%    %%  %%      %%%%  %%%%      %%%%%%%%%%  %%    %%%%    %%  %%  %%  %%  %%%%      %%  %%  %%    %%    %%%%              %%%%  %%%%    %%  %%%%    %%%%        %%    %%    %%    %%  %%    
  %%%%%%  %%%%%%    %%  %%%%%%  %%      %%  %%  %%  %%%%  %%    %%%%%%%%  %%    %%%%    %%%%%%%%  %%  %%%%%%%%  %%%%%%%%%%    %%%%%%%%  %%        %%  %%%%%%%%  %%      %%  %%      %%  %%        %%  %%%%%%%%  %%      %%    %%  %%%%    %%%%%%%%    
      %%%%%%      %%  %%  %%%%%%  %%%%%%  %%%%        %%    %%%%%%%%    %%  %%  %%%%    %%%%%%%%      %%  %%%%%%%%%%  %%%%%%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%    %%%%%%%%%%%%%%%%  %%        %%  %%%%%%%%  %%  %%%%  %%%%%%%%%%%%%%  %%      
  %%    %%  %%%%%%%%    %%%%%%  %%%%%%      %%      %%        %%  %%    %%  %%%%%%%%        %%%%  %%%%  %%  %%  %%      %%%%        %%%%%%        %%%%  %%          %%  %%%%    %%    %%%%        %%%%  %%    %%    %%        %%%%    %%%%%%  %%      
          %%    %%  %%%%    %%%%%%%%%%        %%%%  %%%%%%%%%%  %%%%%%%%  %%  %%  %%  %%%%%%  %%%%%%      %%%%%%          %%%%  %%  %%    %%%%%%%%  %%            %%%%  %%%%  %%%%%%      %%    %%  %%%%%%        %%      %%%%%%      %%  %%%%    %%  
  %%%%  %%  %%%%%%%%      %%%%%%%%  %%          %%  %%%%%%  %%    %%    %%%%  %%  %%  %%%%%%    %%%%%%  %%  %%%%    %%      %%    %%      %%  %%%%%%%%  %%        %%  %%%%    %%  %%      %%  %%%%%%%%  %%        %%  %%%%%%%%            %%%%        
  %%  %%%%%%%%  %%  %%%%  %%  %%  %%  %%%%  %%        %%        %%%%%%%%%%%%%%%%  %%%%%%%%%%      %%%%%%%%    %%  %%%%    %%%%%%  %%%%        %%  %%%%%%%%  %%        %%            %%        %%  %%%%%%%%  %%        %%  %%%%%%    %%      %%    %%  
    %%%%%%    %%%%  %%%%%%%%%%  %%%%%%  %%  %%%%%%        %%%%%%%%%%%%%%%%%%%%%%      %%%%%%%%%%%%%%  %%    %%  %%%%%%%%%%%%      %%%%  %%%%%%                %%%%%%  %%  %%%%%%%%%%%%  %%%%  %%%%%%  %%    %%    %%  %%%%%%%%%%  %%%%%%%%%%%%%%%%%%  
                  %%  %%        %%    %%%%  %%    %%%%%%  %%      %%%%      %%%%  %%%%    %%%%%%    %%    %%%%  %%%%      %%%%  %%  %%%%%%        %%%%        %%%%%%%%%%  %%      %%%%  %%    %%%%  %%%%  %%%%  %%    %%%%    %%%%%%      %%  %%%%%%  
  %%%%%%%%%%%%%%  %%%%%%      %%%%%%  %%%%%%    %%      %%%%  %%  %%%%%%%%%%    %%  %%%%%%%%    %%        %%  %%  %%  %%  %%      %%  %%%%%%%%  %%        %%%%  %%%%%%    %%  %%  %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%  %%%%    %%  
  %%          %%  %%%%    %%%%  %%%%%%    %%    %%    %%  %%      %%%%%%  %%%%  %%  %%%%%%  %%%%%%  %%          %%%%      %%%%        %%  %%%%%%%%  %%      %%    %%%%%%%%%%      %%  %%  %%%%%%%%  %%            %%%%%%%%  %%  %%%%      %%          
  %%  %%%%%%  %%    %%  %%  %%  %%%%    %%%%%%%%%%  %%%%%%%%%%%%%%%%      %%  %%  %%  %%%%          %%  %%%%  %%  %%%%%%%%%%%%  %%%%    %%%%%%%%    %%  %%  %%    %%  %%  %%%%%%%%%%    %%%%  %%    %%%%%%%%%%  %%  %%%%%%        %%%%%%%%%%%%    %%  
  %%  %%%%%%  %%  %%%%  %%      %%  %%  %%  %%  %%  %%%%    %%%%%%%%    %%%%  %%      %%  %%%%  %%%%        %%%%        %%%%    %%%%    %%  %%%%%%%%    %%    %%      %%    %%  %%  %%%%          %%    %%%%%%%%%%      %%%%%%    %%    %%%%      %%  
  %%  %%%%%%  %%  %%  %%%%%%  %%%%%%%%    %%%%            %%%%    %%%%  %%%%  %%%%%%      %%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%            %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%          %%%%%%%%    
  %%          %%      %%%%    %%%%  %%    %%%%  %%      %%      %%%%  %%%%%%          %%%%%%%%%%      %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%  %%%%%%%%  %%        %%%%%%      %%  %%      
  %%%%%%%%%%%%%%  %%%%          %%      %%          %%%%  %%    %%%%%%      %%      %%      %%%%%%%%    %%      %%%%    %%            %%%%        %%    %%%%%%%%        %%%%      %%  %%  %%%%  %%%%%%  %%    %%%%  %%%%%%      %%%%%%  %%    %%%%%%  
                                                                                                                                                                                                                                                      
""")
    }
    
    func testTooLarge() {
        for (level, max) in zip(QRErrorCorrectLevel.allCases, [2953, 2331, 1663, 1273]) {
            let length = max + 1
            print("Try overflow error correct level \(level) with length of \(length)")
            let content = randomStringOfUTF8Length(length)
            print("Generated random string of length \(content.count), utf8 count \(content.utf8.count)")
            XCTAssertThrowsError(try QRCode(content, errorCorrectLevel: level))
        }
    }
    
    func testAllLevelMax() throws {
        for limits in ([[0, 0, 0, 0]] + QRCodeType.QRCodeLimitLength).lazy.reversed() {
            for (level, length) in zip(QRErrorCorrectLevel.allCases, limits) {
                print("Try error correct level \(level), utf8 count: \(length)")
                let content = randomStringOfUTF8Length(length)
                print("Generated a random string, str length: \(content.count)")
                XCTAssertNoThrow(try QRCode(content, errorCorrectLevel: level))
            }
        }
    }

    static var allTests = [
        ("testSimple", testSimple),
        ("testLowErrorCorrectLevel", testLowErrorCorrectLevel),
        ("testBorderless", testBorderless),
        ("testEFQRCode", testEFQRCode),
        ("testEmpty", testEmpty),
        ("testStressWithPi", testStressWithPi),
        ("testTooLarge", testTooLarge),
        ("testAllLevelMax", testAllLevelMax),
    ]
}
